﻿namespace eeenno.SpeeedReaderUI.NativeWebBrowser.Win32
{
    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Windows.Forms;

    public class Win32Window
    {
        private IntPtr hWnd;

        private Win32Window()
        {
        }

        public Win32Window(IntPtr hWnd)
        {
            this.hWnd = hWnd;
        }

        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr CallWindowProc(IntPtr pfn, IntPtr hWnd, WM msg, IntPtr wParam, IntPtr lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr CallWindowProc(IntPtr pfn, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
        [DllImport("coredll.dll", EntryPoint="CreateWindowExW", SetLastError=true)]
        public static extern IntPtr CreateWindowEx(int dwExStyle, string lpClassName, string lpWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern int DefWindowProc(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr DestroyWindow(IntPtr hWnd);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr FindWindow(string className, string wndName);
        public static Win32Window FromControl(Control c)
        {
            c.Capture = true;
            IntPtr capture = GetCapture();
            c.Capture = false;
            if (capture == IntPtr.Zero)
            {
                throw new Exception("Unable to capture window");
            }
            return new Win32Window(capture);
        }

        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr GetActiveWindow();
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr GetCapture();
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr GetFocus();
        public Win32Window GetWindow(GW nCmd)
        {
            return new Win32Window(GetWindow(this.hWnd, nCmd));
        }

        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr GetWindow(IntPtr hWnd, GW nCmd);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern int GetWindowLong(IntPtr hWnd, int nItem);
        public static Rectangle GetWindowRect(IntPtr hWnd)
        {
            byte[] rect = new byte[0x10];
            if (!GetWindowRect(hWnd, rect))
            {
                throw new WinAPIException("Failed getting window rectangle");
            }
            int x = BitConverter.ToInt32(rect, 0);
            int y = BitConverter.ToInt32(rect, 4);
            int width = BitConverter.ToInt32(rect, 8) - x;
            return new Rectangle(x, y, width, BitConverter.ToInt32(rect, 12) - y);
        }

        [DllImport("coredll.dll", SetLastError=true)]
        public static extern bool GetWindowRect(IntPtr hWnd, byte[] rect);
        public static string GetWindowText(IntPtr hWnd)
        {
            StringBuilder sb = new StringBuilder(0x100);
            int num = GetWindowText(hWnd, sb, sb.Capacity);
            if (num > 0)
            {
                sb.Length = num;
            }
            return sb.ToString();
        }

        [DllImport("coredll.dll", SetLastError=true)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder sb, int maxCount);
        [DllImport("commctrl.dll", SetLastError=true)]
        public static extern bool InitCommonControlsEx(byte[] data);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr MoveWindow(IntPtr hWnd, int X, int Y, int cx, int cy);
        public static implicit operator IntPtr(Win32Window wnd)
        {
            return wnd.hWnd;
        }

        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern int RegisterWindowMessage(string lpMsg);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, byte[] lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, string lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, string lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, byte[] lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, int lParam);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern bool SetFocus(IntPtr hWnd);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern IntPtr SetParent(IntPtr hWChild, IntPtr hwParent);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern void SetWindowLong(IntPtr hWnd, int GetWindowLongParam, int nValue);
        [DllImport("coredll.dll", SetLastError=true)]
        public static extern int SetWindowPos(IntPtr hWnd, HWND pos, int X, int Y, int cx, int cy, SWP uFlags);
        public static void SetWindowStyle(IntPtr hwnd, int style)
        {
            SetWindowLong(hwnd, -16, style);
            SetWindowPos(hwnd, HWND.TOP, 0, 0, 0, 0, SWP.DRAWFRAME | SWP.NOACTIVATE | SWP.NOZORDER | SWP.NOMOVE | SWP.NOSIZE);
        }

        public static void UpdateWindowStyle(IntPtr hwnd, int RemoveStyle, int AddStyle)
        {
            int nValue = GetWindowLong(hwnd, -16) & ~RemoveStyle;
            nValue |= AddStyle;
            SetWindowLong(hwnd, -16, nValue);
            SetWindowPos(hwnd, HWND.TOP, 0, 0, 0, 0, SWP.DRAWFRAME | SWP.NOACTIVATE | SWP.NOZORDER | SWP.NOMOVE | SWP.NOSIZE);
        }

        public IntPtr Handle
        {
            get
            {
                return this.hWnd;
            }
        }

        public string Text
        {
            get
            {
                return GetWindowText(this.hWnd);
            }
        }
    }
}

